package org.zoomdev.zoom.dao.transaction;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zoomdev.zoom.dao.Dao;
import org.zoomdev.zoom.dao.DaoException;
import org.zoomdev.zoom.dao.modules.CoreDaoModule;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class TransBase {
    protected static final Logger log = LoggerFactory.getLogger(CoreDaoModule.NAME);

    private Connection connection;
    private DataSource dataSource;
    private Transactions transRef;

    private boolean autoReleaseConnection;
    private Dao dao;

    public Connection getConnection() {
        return connection;
    }

    public void setConnection(Connection connection) {
        this.connection = connection;
    }

    public Connection openConnection() {
        Connection connection = this.connection;
        if (connection != null) {
            return connection;
        }
        try {
            Transactions transactions = transRef;
            if (transactions == null) {
                connection = dataSource.getConnection();
            } else {
                connection = transactions.openConnection(dataSource);
            }
            this.connection = connection;
            return connection;
        } catch (SQLException e) {
            throw new DaoException("获取数据库连接失败", e);
        }
    }

    public void beginTrans(TransactionLevel level) {
        Transactions transactions = this.transRef;
        if (transactions == null) {
            transactions = new Transactions(level);
            this.transRef = transactions;
        } else {
            transactions.addRefCount();
        }
    }

    public Transactions getTransactions() {
        return transRef;
    }

    public void rollbackTrans() {
        if (0 == transRef.subRefCount()) {
            try {
                transRef._rollback();
            } finally {
                removeTrans();
            }
        }
    }

    public void removeTrans() {
        this.transRef = null;
    }

    public void commitTrans() {
        if (0 == transRef.subRefCount()) {
            try {
                transRef._commit();
            } finally {
                removeTrans();
            }
        }
    }

    public void releaseConnection() {
        if (!autoReleaseConnection) {
            return;
        }

        Connection connection = this.connection;
        if (connection == null) {
            return;
        }
        Transactions transactions = transRef;
        if (transactions == null) {
            try {
                connection.close();
            } catch (Throwable e) {
                log.error("关闭连接失败", e);
            }
        }
        this.connection = null;
    }

    public void setAutoReleaseConnection(boolean autoReleaseConnection) {
        this.autoReleaseConnection = autoReleaseConnection;
    }

    public Dao getDao() {
        return dao;
    }

    public void setDao(Dao dao) {
        this.dao = dao;
        this.dataSource = dao.getDataSource();
    }
}
